package com.sbl.utils;

import javax.sql.DataSource;
import java.sql.Connection;

/**
 * 连接的工具类，它用于从数据源中获取一个连接，并且实现和线程的绑定
 *    频繁的创建和销毁连接，资源浪费，所以引入了连接池的概念（连接池可以存放多条连接）
 *    ThreadLocal能够实现当前现场操作的都是同一个连接Connection（管道），保证了事务=====
 *                                                                      多线程执行同一事务，大概率出乱，它执行一下，它又执行一下
 *                                                                      绑定之后：连接是一个（多条连接，合并成一个事务），线程是一个
 */
public class ConnectionUtils {

    // ThreadLocal 是一个数据结构，有点像HashMap，键值对，但是一个ThreadLocal只能保存一个，并且各个线程之间互不干扰
    /**
     * ThreadLocal<String> localName = new ThreadLocal();
     * localName.set("小龙");
     * String name = localName.get();
     *
     * 每个线程中都有一个ThreadLocalMap数据结构
     */
    private ThreadLocal<Connection> tl = new ThreadLocal<Connection>();

    private DataSource dataSource;

    public void setDataSource(DataSource dataSource) {
        this.dataSource = dataSource;
    }

    /**
     * 获取当前线程上的连接
     * @return
     */
    public Connection getThreadConnection() {
        try{
            //1.先从ThreadLocal上获取
            Connection conn = tl.get();
            //2.判断当前线程上是否有连接
            if (conn == null) {
                //3.从数据源中获取一个连接，并且存入ThreadLocal中
                conn = dataSource.getConnection();
                tl.set(conn);
            }
            //4.返回当前线程上的连接
            return conn;
        }catch (Exception e){
            throw new RuntimeException(e);
        }
    }

    /**
     * 把连接和线程解绑
     */
    public void removeConnection(){
        tl.remove();
    }
}
